#region License

// This file is part of Grawlix.
// 
// Grawlix is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as
// published by the Free Software Foundation, either version 3 of
// the License, or (at your option) any later version.
// Grawlix is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
// 
// You should have received a copy of the GNU General Public
// License along with Grawlix.  If not, see
// <http://www.gnu.org/licenses/>.

#endregion

using System.Globalization;
using Grawlix.Geometry;

namespace Grawlix.Application.Gui.Messages
{
	/// <summary>
	/// Base class of mouse input messages.
	/// </summary>
	public abstract class MouseInputMessage : InputMessage
	{
		/// <summary>
		/// The position of the mouse.
		/// </summary>
		private Vector2 _position;

		/// <summary>
		/// The position of the mouse.
		/// </summary>
		public Vector2 Position
		{
			get { return _position; }
			set { _position = value; }
		}

		/// <summary>
		/// Returns a <see cref="T:System.String"/> that represents the
		/// current <see cref="T:System.Object"/>.
		/// </summary>
		/// <returns>
		/// A <see cref="T:System.String"/> that represents the current
		/// <see cref="T:System.Object"/>.
		/// </returns>
		public override string ToString()
		{
			return string.Format(CultureInfo.InvariantCulture,
			                     "Position: {0}", _position);
		}
	}

	/// <summary>
	/// A notification that the mouse has just entered or left a control.
	/// </summary>
	public abstract class MouseBoundaryInputMessage :
		MouseInputMessage
	{
		/// <summary>
		/// Whether the mouse has just entered the control.
		/// </summary>
		private bool _enter;

		/// <summary>
		/// Whether the mouse has just entered the control.
		/// </summary>
		public bool Enter
		{
			get { return _enter; }
			set { _enter = value; }
		}

		/// <summary>
		/// Returns a <see cref="T:System.String"/> that represents the
		/// current <see cref="T:System.Object"/>.
		/// </summary>
		/// <returns>
		/// A <see cref="T:System.String"/> that represents the current
		/// <see cref="T:System.Object"/>.
		/// </returns>
		public override string ToString()
		{
			return string.Format(CultureInfo.InvariantCulture,
			                     "{0}, Enter: {1}", base.ToString(),
			                     _enter);
		}
	}

	/// <summary>
	/// A notification that the mouse has just entered a control.
	/// </summary>
	public class MouseEnterInputMessage :
		MouseBoundaryInputMessage
	{
		/// <summary>
		/// Initializes a new instance of the 
		/// <see cref="MouseEnterInputMessage"/> class.
		/// </summary>
		public MouseEnterInputMessage()
		{
			Enter = true;
		}
	}

	/// <summary>
	/// A notification that the mouse has just left a control.
	/// </summary>
	public class MouseLeaveInputMessage :
		MouseBoundaryInputMessage
	{
		/// <summary>
		/// Initializes a new instance of the 
		/// <see cref="MouseLeaveInputMessage"/> class.
		/// </summary>
		public MouseLeaveInputMessage()
		{
			Enter = false;
		}
	}

	/// <summary>
	/// A notification that the mouse has moved.
	/// </summary>
	public class MouseMoveInputMessage : MouseInputMessage
	{
		/// <summary>
		/// The change in mouse position.
		/// </summary>
		/// <remarks>There could be a difference if you calculate this
		/// manually.</remarks>
		private Vector2 _delta;

		/// <summary>
		/// The change in mouse position.
		/// </summary>
		/// <remarks>There could be a difference if you calculate this
		/// manually.</remarks>
		public Vector2 Delta
		{
			get { return _delta; }
			set { _delta = value; }
		}

		/// <summary>
		/// Returns a <see cref="T:System.String"/> that represents the
		/// current <see cref="T:System.Object"/>.
		/// </summary>
		/// <returns>
		/// A <see cref="T:System.String"/> that represents the current
		/// <see cref="T:System.Object"/>.
		/// </returns>
		public override string ToString()
		{
			return string.Format(CultureInfo.InvariantCulture,
			                     "{0}, Delta: {1}", base.ToString(),
			                     _delta);
		}
	}

	/// <summary>
	/// A notification that the mouse wheel has been turned.
	/// </summary>
	public class MouseWheelInputMessage : MouseInputMessage
	{
		/// <summary>
		/// The number of ticks the wheel has moved.
		/// </summary>
		private int _ticks;

		/// <summary>
		/// The number of ticks the wheel has moved.
		/// </summary>
		public int Ticks
		{
			get { return _ticks; }
			set { _ticks = value; }
		}

		/// <summary>
		/// Returns a <see cref="T:System.String"/> that represents the
		/// current <see cref="T:System.Object"/>.
		/// </summary>
		/// <returns>
		/// A <see cref="T:System.String"/> that represents the current
		/// <see cref="T:System.Object"/>.
		/// </returns>
		public override string ToString()
		{
			return string.Format(CultureInfo.InvariantCulture,
			                     "{0}, Ticks: {1}", base.ToString(),
			                     _ticks);
		}
	}

	/// <summary>
	/// A notification for when the mouse has been clicked.
	/// </summary>
	public abstract class MouseClickInputMessage :
		MouseInputMessage
	{
		/// <summary>
		/// The button that was pressed.
		/// </summary>
		private int _code;

		/// <summary>
		/// Whether the button is down.
		/// </summary>
		private bool _down;

		/// <summary>
		/// The button that was pressed.
		/// </summary>
		public int Code
		{
			get { return _code; }
			set { _code = value; }
		}

		/// <summary>
		/// Whether the button is down.
		/// </summary>
		public bool Down
		{
			get { return _down; }
			set { _down = value; }
		}

		/// <summary>
		/// Returns a <see cref="T:System.String"/> that represents the
		/// current <see cref="T:System.Object"/>.
		/// </summary>
		/// <returns>
		/// A <see cref="T:System.String"/> that represents the current
		/// <see cref="T:System.Object"/>.
		/// </returns>
		public override string ToString()
		{
			return string.Format(CultureInfo.InvariantCulture,
			                     "{0}, Code: {1}, Down: {2}",
			                     base.ToString(), _code, _down);
		}
	}

	/// <summary>
	/// A notification that a mouse button has been pressed.
	/// </summary>
	public class MouseDownInputMessage : MouseClickInputMessage
	{
		/// <summary>
		/// Initializes a new instance of the 
		/// <see cref="MouseDownInputMessage"/> class.
		/// </summary>
		public MouseDownInputMessage()
		{
			Down = true;
		}
	}

	/// <summary>
	/// A notification that a mouse button has been released.
	/// </summary>
	public class MouseUpInputMessage : MouseClickInputMessage
	{
		/// <summary>
		/// Initializes a new instance of the 
		/// <see cref="MouseUpInputMessage"/> class.
		/// </summary>
		public MouseUpInputMessage()
		{
			Down = false;
		}
	}
}